/**
 * Game：游戏类，控制游戏的分数，状态，游戏容器，提供开始和结束等功能
 *   因为当前游戏只有一个，Game这个代表了游戏的对象同时只会存在一个，不需要有多个
 *   所以：我们采用单例的模式来设计这个Game对象
 * 
 *   在js中我们可以直接通过对象字面量的方式来创建一个单例对象，而不需要通过class(构造函数)来创建
 * 
 */
import WaterPolo from './WaterPolo.js';
import Bullte from './Bullte.js';


export default {
   // 水量，默认是10，当water为0的时候，代表游戏结束
   water: 10,
   // 保存当前游戏的容器
   wrap: null,
   // 数字
   txt:null,
   // 保存了游戏中所有小水球对象
   waterPolos:[],
   // 保存游戏中所有子弹的数组
   bullets:[],
   // 保存当前水滴的容器
   value:0,
   /**
    *开始游戏的方法，当这个方法调用，用户就可以玩游戏 
    *
    */
   start() {
      // 对游戏进行初始化，提供用户可以操作的一些动作

      // 处理一些逻辑中的程序错误
      if (this.wrap == null) throw new Error('请设置游戏的容器');
      this.txt.innerHTML = this.water;
      this.value.style.height = this.water * 20 + 'px';

      for (let i = 0; i < 36; i++) {
         // 使用传统面向过程的一种方式来创建水球创建结构
         // let div = document.createElement('div');
         // div.classList.add('water-polo');
         // let img = document.createElement('img');
         // img.src = "img/1.png";
         // div.appendChild(img);
         // this.wrap.appendChild(div);
         
         // 使用面向对象的方式
         // 一个类内部只关注有哪些特性(属性,方法)，但是一些非自身的逻辑我们不在内部实现，是通过类对外提供的方法或事件来实现。
         let waterPolo = new WaterPolo(Math.floor(Math.random() * 5));
         this.waterPolos.push(waterPolo);

         waterPolo.draw(this.wrap);
         // 当被点击时做的事情
         waterPolo.onclick = () => {
            if(this.water > 0){
               this.water--;
               waterPolo.levelUp();
               this.txt.innerHTML = this.water;
               this.value.style.height = this.water * 20 + 'px';
               if(this.water == 0) return console.log('游戏结束！');
            }
         }
         // 当爆炸时做的事情
         waterPolo.onboom = () => {
            // ←
            let BullteLeft = new Bullte('left',2);
            this.bullets.push(BullteLeft);
            BullteLeft.draw(this.wrap);
            // 小水滴定位到点击爆炸的位置
            // 不推荐直接操作dom - waterPolo.js中定义属性
            BullteLeft.setPosition(waterPolo.left - 50,waterPolo.top);
            BullteLeft.onmove = () => {
               this.bulletMove(waterPolo,BullteLeft);
            }

            // →
            let BullteRight = new Bullte('right',2);
            this.bullets.push(BullteRight);
            BullteRight.draw(this.wrap);
            // 小水滴定位到点击爆炸的位置
            // 不推荐直接操作dom - waterPolo.js中定义属性
            BullteRight.setPosition(waterPolo.left + 50,waterPolo.top);
            BullteRight.onmove = () => {
               this.bulletMove(waterPolo,BullteRight);
            }

            // ↑
            let BullteTop = new Bullte('top',2);
            this.bullets.push(BullteTop);
            BullteTop.draw(this.wrap);
            // 小水滴定位到点击爆炸的位置
            // 不推荐直接操作dom - waterPolo.js中定义属性
            BullteTop.setPosition(waterPolo.left,waterPolo.top - 50);
            BullteTop.onmove = () => {
               this.bulletMove(waterPolo,BullteTop);
            }

            // ↓
            let BullteBottom = new Bullte('bottom',2);
            this.bullets.push(BullteBottom);
            BullteBottom.draw(this.wrap);
            // 小水滴定位到点击爆炸的位置
            // 不推荐直接操作dom - waterPolo.js中定义属性
            BullteBottom.setPosition(waterPolo.left,waterPolo.top + 50);
            BullteBottom.onmove = () => {
               this.bulletMove(waterPolo,BullteBottom);
            }
         }
      }
   },
   bulletMove(waterPolo,bullet){
      // 碰撞检测
      // 排除发射水滴的元素与level等级为0的元素
      let waterPolos = this.waterPolos.filter( wp => {
         return wp != waterPolo && wp.level > 0;
      });
      let wp = bullet.collision(waterPolos);
      // 如果碰撞了，销毁水滴
      if(wp){
         bullet.desctory();
         // 被碰撞的水球需要升级
         wp.levelUp();
         // 保留没销毁的水滴
         this.bullets = this.bullets.filter( bu => bu != bullet);
      }

      // 判断水滴超出容器范围销毁水滴
      if(bullet.left < -bullet.width || bullet.left > this.wrap.offsetWidth || bullet.top < -bullet.height || bullet.top > this.wrap.offsetHeight){
         bullet.desctory();
         // 保留没销毁的水滴
         this.bullets = this.bullets.filter( bu => bu != bullet);
      }

      // 判断当前水滴都销毁之后
      if(this.bullets.length == 0){
         // 得出页面中还有的水滴
         let wps = this.waterPolos.filter(wp => wp.level !== 0);
         if(this.water === 0){
            console.log('游戏结束！');
            return;
         }

         if(wps.length === 0 && this.water > 0){
            console.log('进入下一关！');
            return;
         }
      }
   }
};

// - 水滴爆炸计分 -